using Kaleida.ServiceMonitor.Model.Runtime;
using NUnit.Framework;

namespace Kaleida.UnitTests.Model.Runtime
{
    [TestFixture]
    public class ReflectionExtensionsTests
    {
        public class DerivationTestSubjectA { }
        public class DerivationTestSubjectB : DerivationTestSubjectA { }
        public class DerivationTestSubjectC : DerivationTestSubjectB { }
        public class DerivationTestSubjectD { }

        [Test]
        public void TestDerivesFrom()
        {
            Assert.IsFalse(typeof(DerivationTestSubjectA).DerivesFrom(typeof(DerivationTestSubjectB)));
            Assert.IsTrue(typeof(DerivationTestSubjectB).DerivesFrom(typeof(DerivationTestSubjectA)));
            Assert.IsTrue(typeof(DerivationTestSubjectC).DerivesFrom(typeof(DerivationTestSubjectA)));
            Assert.IsFalse(typeof(DerivationTestSubjectC).DerivesFrom(typeof(DerivationTestSubjectD)));
        }


        public class ConstructorTestSubjectA { }
        public class ConstructorTestSubjectB
        {
            public ConstructorTestSubjectB() { }
        }

        public class ConstructorTestSubjectC
        {
            public ConstructorTestSubjectC(string a, string b) { }
        }

        public class ConstructorTestSubjectD
        {
            private ConstructorTestSubjectD(string a, int b) { }
        }

        [Test]
        public void TestHasPublicFullyStringParameterisedConstructor()
        {
            Assert.IsTrue(typeof(ConstructorTestSubjectA).HasPublicFullyStringParameterisedConstructor(0));
            Assert.IsFalse(typeof(ConstructorTestSubjectA).HasPublicFullyStringParameterisedConstructor(1));

            Assert.IsTrue(typeof(ConstructorTestSubjectB).HasPublicFullyStringParameterisedConstructor(0));
            Assert.IsFalse(typeof(ConstructorTestSubjectB).HasPublicFullyStringParameterisedConstructor(1));
            
            Assert.IsFalse(typeof(ConstructorTestSubjectC).HasPublicFullyStringParameterisedConstructor(0));
            Assert.IsFalse(typeof(ConstructorTestSubjectC).HasPublicFullyStringParameterisedConstructor(1));
            Assert.IsTrue(typeof(ConstructorTestSubjectC).HasPublicFullyStringParameterisedConstructor(2));
            Assert.IsFalse(typeof(ConstructorTestSubjectC).HasPublicFullyStringParameterisedConstructor(3));
            
            Assert.IsFalse(typeof(ConstructorTestSubjectD).HasPublicFullyStringParameterisedConstructor(2));
        }


        [Test]
        public void TestToPascalCase()
        {
            Assert.AreEqual("Singleword", "singleword".ToPascalCase());
            Assert.AreEqual("MyActionName", "my-action-name".ToPascalCase());
            Assert.AreEqual("", "".ToPascalCase());
            Assert.AreEqual("MyWordswithMixedstyles", "My-wordsWith-mixedStyles".ToPascalCase());
            Assert.AreEqual("WascallyWabbitWuns", "wascally-wabbit-wuns".ToPascalCase(), "Alliterative names are converted correctly");
        }

        [Test]
        public void TestToDashSeparated()
        {
            Assert.AreEqual("singleword", "singleword".ToDashSeparated());
            Assert.AreEqual("my-action-name", "MyActionName".ToDashSeparated());
            Assert.AreEqual("wascally-wabbit-wuns", "WascallyWabbitWuns".ToDashSeparated(), "Alliterative names are converted correctly");
            Assert.AreEqual("", "".ToDashSeparated());
        }
       
    }
}